home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Utilities Professional 1-1500
/
Utilities Professional 1-1500 (1994)(WPD)[!].iso
/
12511500
/
var1312.dms
/
var1312.adf
/
HP11
/
IO.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-11
|
9KB
|
325 lines
#include "exec/types.h"
#include "stdlib.h"
#include "stdio.h"
#include <math.h>
#include "string.h"
#include "hp11/hp11.h"
#include "hp11/amiga/amiga.h"
#include "hp11/ins.h"
#include "hp11/io.h"
#include "hp11/kbd.h"
#include "hp11/codes.h"
#include "hp11/prog_codes.h"
#define MAXRUN 4 /* Length of time running is displayed */
#define FOREVER for (;;)
int comma;
static char *stpich(char *p, int c) /* insert character c at front of string p */
{
movmem(p, p + 1, strlen(p) + 1);
*p = c;
return(p);
}
int GetKey() /* Read a key & wait for its release */
{
int key;
key = PollKey(TRUE);
RelKey();
return(key);
}
enum KeyTypes ReadKey(code) /* Read a complete key sequence, & return
its type, intrsuction or action. */
register WORD *code;
{
register struct Key *curtkey;
register int key, offset;
register BOOL noKey; /* if an invalid sequence is returned, don't read a new key,
reuse the one which caused the error. This is set to false when that happens */
register enum KeyTypes ret;
noKey = TRUE; /* no key read */
FOREVER {
offset = 0; /* f or g not pressed */
FOREVER { /* This loop reads a key from the main, f or g shifted keyboards.
Further refinements (eg sto) are done algorithmically, to save space */
if (noKey) key = PollKey(TRUE); /* obtain next key */
Dispf(FALSE); Dispg(FALSE);
noKey = TRUE;
if (key == 31) { /* f pressed, toggle its status */
offset = (offset == NUMKEYS) ? 0 : (Dispf(TRUE), NUMKEYS);
RelKey();
}
else if (key == 32) { /* g */
offset = (offset == NUMKEYS + NUMKEYS) ? 0 : (Dispg(TRUE), NUMKEYS + NUMKEYS);
RelKey();
}
else break;/* got a key, exit from loop */
}
if (User && key < 5) offset ^= NUMKEYS; /* Toggle f for first five keys. This
doesn't affect g because the bit patterns are exclusive (42 & 84 = 0) */
Dispf(FALSE); Dispg(FALSE);
curtkey = mainKbd + offset + key; /* find address of (eventually shifted) key */
switch (curtkey->Sort) {
case Action:
*code = curtkey->Act;
return(Action);
case Instruction:
*code = curtkey->Code;
return(Instruction);
case Prefix: /* Key is a prefix, execute corresponding routine */
RelKey();
ret = (*(curtkey->Suffix))(code);
if (ret != Invalid) return(ret); /* if successful */
key = *code; /* else, invalid keycode returnedin code field for reuse */
noKey = FALSE; /* a key is already available */
break;
case Invalid: /* An inavlid f or g sequence was entered, retry it with
the f or g prefix stripped. Therefore all obtainable main keyboard sequences
must exist, otherwise the program enters an infinite loop retrying constantly
the same nonexistent keycode */
key %= NUMKEYS;
noKey = FALSE;
break;
}
}
}
/* Return position n on the liquid cristal display in string t */
int scrpos(t, n)
char *t;
register int n;
{
register char *s = t;
register int pos;
pos = 0;
while (pos <= n && *s) { /* go on till end of string or beyond position n on display */
if (*s != '.' && *s != ',') pos++; /* . & , take no space on the display */
s++;
}
return((int)((s - t) - 1 - (pos - n))); /* pos - n is there to take care of the overshoot. If
n is beyond the end of the string, the position returned may well be wildly beyond the
actual end of the string */
}
/* Return the length taken up on the screen by the string */
int scrlen(s)
register char *s;
{
register int cnt = 0;
while (*s) {
if (*s != '.' && *s != ',') cnt++; /* . & , take no space on the display */
s++;
}
return(cnt);
}
/* format string s in hp11 display format (without exponent) so that it takes
n spaces in the display. s isn't modified */
static char *CvtStd(char *s, int n)
{
static char buf[20];
register char *p;
register int i, nb;
register int digit_separator = comma ? '.' : ','; /* separator according to current setting */
strcpy(buf, s); /* copy string to safe work buffer */
if ((p = strchr(buf, '.')) == NULL) { /* find position of . */
p = buf + strlen(buf);
if (!entering) *p = comma ? ',' : '.';
*(p + 1) = '\0';
}
else if (comma) *p = ','; /* Replace . by , if necessary */
while ((p -= 3) - buf > 1) /* Add , (or .) to string every 3 digits */
stpich(p, digit_separator);
nb = n - scrlen(buf);
for (i = 1; i <= nb; i++) strcat(buf, " "); /* pad with spaces to required screen length */
buf[scrpos(buf, n) + 1] = '\0'; /* cut at n characters */
return(buf);
}
/* format string s in hp11 display format (with exponent) */
static char *CvtExpo(char *s, char *e)
{
if (strlen(e) > 3) { /* deal with roundoff towards 1e100 when nb too big */
e = " 99"; /* exponent is 99 */
strncpy(s + 1, "9.999999999", strlen(s + 1)); /* mantissa is enough 9's */
}
return(strcat(CvtStd(s, 8), e));
}
/* convert x to scientific format with n digits. Returns it in a static buffer (from CvtStd) */
static char *Scient(double x, int n)
{
char buf[20];
register char *pe;
sprintf(buf, "% .*E", n, x); /* Scientific format with n digits */
pe = strchr(buf, 'E'); /* split string into mantissa & exponent */
*pe++ = '\0';
/* if (*pe == '+') *pe = ' '; A + is displayed as a space by the Display routine anyway */
return(CvtExpo(buf, pe));
}
/* Convert x to fix n format */
static char *Fixed(double x, int n)
{
char buf[80];
sprintf(buf, "% .*f", n, x);
return(CvtStd(buf, 11));
}
/* Eng n format */
static char *Engin(double x, int n)
{
char expbuf[10], buf[80];
register char *pe;
double mantissa;
register int exponent, dif;
sprintf(buf, "%.*E", n, x); /* print enough digits */
*(pe = strchr(buf, 'E')) = '\0';
mantissa = atof(buf); /* get mantissa & exponent */
exponent = atoi(pe + 1);
/* Round exponent down to a multiple of 3 */
dif = exponent % 3;
if (dif < 0) dif += 3;
exponent -= dif; /* calculate new exponent & mantissa */
mantissa *= pow(10.0, (double)dif);
/* Convert them to string */
sprintf(buf, "% .*f", (n - dif > 0) ? n - dif : 0, mantissa);
sprintf(expbuf, "%c%02d", (exponent < 0) ? '-' : ' ', iabs(exponent)); /* pad exponent with 0's, hence %02d not %2d */
return(CvtExpo(buf, expbuf));
}
/* Display current trig mode */
static void DispAngle(void)
{
switch (Angles) {
case grad:DispG(TRUE);
case rad:DispRAD(TRUE);
case deg:break;
}
}
/* Display current x value in normal mode, running in run mode */
void Disp()
{
static int runcnt = MAXRUN;
static BOOL runon;
if (running) { /* Flash running on and off every MAXRUN calls */
if (fast) { /* Display Running only once in fast mode */
if (!runon) {
Display(" Running");
runon = TRUE; /* Running displayed */
}
}
else if (runcnt-- == 0) Display("");
else if (runcnt <= -MAXRUN) {
runcnt = MAXRUN;
Display(" Running");
}
}
else {
runon = FALSE; /* Running not displayed */
if (entering) /* Display number entry strings */
if (expo) Display(CvtExpo(strx, expx)); /* with exponent */
else Display(CvtStd(strx, 11));
else
Display(NbStr(X));
DispAngle();
if (User) DispUSER(TRUE);
}
}
char *NbStr(x)
double x;
{
switch (Mode) { /* Display x according to display mode */
case fix:if ((fabs(X) >= minfix / 2.0 || X == 0.0) && fabs(X) < 1E10) {
/* Number can be displayed in fix mode */
return(Fixed(X, Digits));
}
/* fall through for call to Scient */
case sci:return(Scient(X, Digits));
case eng:return(Engin(X, Digits));
}
}
/* Display Error n, & wait for a key to be pressed */
void Error(n)
int n;
{
register char *buf;
entering = FALSE; /* end of digit entry */
error = TRUE; /* an error has occured */
buf = " Error ";
buf[8] = n; buf[9] ='\0';
if (!running) RelKey();
Display(buf);
GetKey();
}
/* Display current program line */
void DisplayLine()
{
register int c1 = keycodes[Prog[PC]].c1, c2 = keycodes[Prog[PC]].c2,
c3 = keycodes[Prog[PC]].c3;
char _buf[20], _insbuf[20];
register char *buf = _buf, *insbuf = _insbuf;
register int point = comma ? ',' : '.'; /* separator according to current setting */
sprintf(buf, " %03d-", PC); /* prepare program line */
/* Prepare instruction buffer */
if (PC == 0) insbuf[0] = '\0'; /* nothing at line 0 */
else switch (keycodes[Prog[PC]].Type) { /* there are 6 methods for displaying a line */
case ONECODE: sprintf(insbuf, "%6d", c1); break; /* nn eg SIN or 9 */
case TWOCODE: sprintf(insbuf, "%3d%3d", c1, c2); break; /* nn nn eg g LOG */
case TWOCODE_9: sprintf(insbuf, "%4d%2d", c1, c2); break; /* nn n eg STO 5*/
case TWOCODE_PT: sprintf(insbuf, "%4d %c%1d", c1, point, c2); break; /* nn .n eg RCL .6 */
case THREECODE: sprintf(insbuf, "%2d,%2d,%2d", c1, c2, c3); break; /* nn,nn,nn eg f HYP SIN */
case THREECODE_PT: sprintf(insbuf, "%2d,%2d, %c%1d", c1, c2, point, c3); break; /* nn,nn, .n eg STO + .0 */
}
Display(strcat(buf, insbuf));
DispAngle();
if (User) DispUSER(TRUE);
}